import 'package:dio/dio.dart';

class NetworkManager {
  static final NetworkManager _singleton = NetworkManager._internal();
  late Dio dio;

  factory NetworkManager() {
    return _singleton;
  }

  NetworkManager._internal();

  void setConfig(NetworkConfig config) {
    var options = BaseOptions(
      baseUrl: config.baseUrl,
      connectTimeout: config.connectTimeout,
      receiveTimeout: config.receiveTimeout,
    );
    dio = Dio(options);
    config.interceptors.forEach((element) {
      dio.interceptors.add(element);
    });
  }

  Future<Map<String, dynamic>?> sendRequest(
      {path,
      data,
      method,
      callback: NetworkCallback,
      isForm: false,
      queryParameters}) async {
    Response<Map<String, dynamic>> r2;
    try {
      if (isForm) {
        var formData = FormData.fromMap(data);
        r2 = await dio.post(path, data: formData);
      } else {
        r2 = await dio.request(path,
            data: data,
            queryParameters: queryParameters,
            options: Options(method: method));
      }
    } catch (e) {
      print("execption!!! $e");
      return null;
    }
    Map<String, dynamic> myMap = new Map<String, dynamic>.from(r2.data!);
    return myMap;
  }

  Future<Map<String, dynamic>?> sendReq(Req req) {
    return sendRequest(path: req.api.path, data: req.data, method: req.api.method,
        callback: null, isForm: req.api.isForm, queryParameters: req.queryParameters);
  }

  // void sendRequest2(model, {path, data, method, callback: NetworkCallback, isForm: false, queryParameters}) async {
  //   Response<Map<String, dynamic>> r2;
  //   try {
  //     if (isForm) {
  //       var formData = FormData.fromMap(data);
  //       r2 = await dio.post(path, data: formData);
  //     } else {
  //       r2 = await dio.request(path,
  //           data: data,
  //           queryParameters: queryParameters,
  //           options: Options(method: method));
  //     }
  //   } catch (e) {
  //     print("execption!!! $e");
  //     return null;
  //   }
  //   try {
  //     Map<String, dynamic> value = new Map<String, dynamic>.from(r2.data!);
  //     print(value);
  //     if (value == null) {
  //       callback.onReqError(-1, "网络错误");
  //     } else if (value['code'] == 0) {
  //       if (model is BaseConvert){
  //         print("ok");
  //         model = model.parseFromMap(value);
  //         callback.onReqSuccess(model, value['code'], value['msg'], path);
  //       } else {
  //         print("not ok");
  //         callback.onReqError(value['code'], '');
  //       }
  //     } else {
  //         callback.onReqError(value['code'], value['msg']);
  //     };
  //     callback.onReqFinish();
  //   } catch(e) {
  //     print('解析错误');
  //     callback.onReqError(-1, '数据错误');
  //     callback.onReqFinish();
  //   }
  // }
}

class NetworkConfig {
  String baseUrl;
  int connectTimeout;
  int receiveTimeout;
  List<Interceptor> interceptors;

  NetworkConfig(
      {required this.baseUrl,
      required this.interceptors,
      this.connectTimeout = 5000,
      this.receiveTimeout = 5000})
      : super();
}

abstract class NetworkCallback {
  void onReqSuccess<T>(T t, int code, String msg, String path);
  void onReqError(int code, String msg);
  void onReqStart();
  void onReqFinish();
}

abstract class BaseConvert<T> {
  T parseFromMap(Map<String, dynamic> map);
}

class NetworkParams {
  final String path;
  final String method;
  final bool isForm;
  NetworkParams(this.path, this.method, {this.isForm = false});
}

class Req {
  NetworkParams api;
  Object model;
  Map<String, dynamic>? data;
  Map<String, dynamic>? queryParameters;

  Req(this.api, this.model, {this.data, this.queryParameters});
}
